Skip to content

2.2. Models

In one glance

  • You will: Explain provider selection, credentials, timeouts, and the optional local model path.
  • You need: A first agent and familiarity with the repository-root .env.
  • Time: about 15 minutes, reference.

Why are the provider and model explicit?

The provider selects the client protocol; the model selects the inference implementation.

entrypoint: AgentEntrypoint = AgentEntrypoint.AGENT
model_provider: ModelProvider = ModelProvider.GEMINI
# Keep the learner and gateway model aligned with the qualified platform pair.
model: str = Field(default="gemini-3.5-flash", min_length=1)

# ``openai-compatible`` describes the ADK client contract, not the
# deployment topology. These defaults support the optional Ollama path;
# Part II instead points the adapter at agentgateway.
openai_base_url: str | None = Field(
    default="http://127.0.0.1:11434/v1",
    validation_alias=AliasChoices("OPENAI_BASE_URL"),
)
openai_api_key: SecretStr | None = Field(
    default=SecretStr("local-ollama"),
    validation_alias=AliasChoices("OPENAI_API_KEY"),
)

# Default Gemini path: an AI Studio API key; optional Enterprise/Vertex via ADC
# with an explicit project and location.
google_api_key: SecretStr | None = Field(
    default=None,
    validation_alias=AliasChoices("GOOGLE_API_KEY"),
)
google_genai_use_enterprise: bool = Field(
    default=False,
    validation_alias=AliasChoices("GOOGLE_GENAI_USE_ENTERPRISE"),
)
google_cloud_project: str | None = Field(
    default=None,
    validation_alias=AliasChoices("GOOGLE_CLOUD_PROJECT"),
)
google_cloud_location: str | None = Field(
    default=None,
    validation_alias=AliasChoices("GOOGLE_CLOUD_LOCATION"),
)

The default is native Gemini with an API key. The optional OpenAI-compatible adapter connects to Ollama or agentgateway. openai-compatible does not mean an OpenAI-hosted model: it names the transport contract.

How does the application construct its model?

One factory constructs the configured ADK client without changing the domain tools.

def build_model() -> str | BaseLlm:
    """Return the configured ADK model implementation.

    The default Gemini mode uses ADK's native integration. The alternate mode
    uses ADK's OSS OpenAI-compatible client; ``OPENAI_BASE_URL`` chooses direct
    Ollama or an agentgateway route without changing application code. When
    ``AGENT_MODEL_FALLBACK`` names a second model, ADK's ``FallbackModel`` tries
    it on the same provider after a retriable 429/5xx from the primary, and only
    before the primary has produced any output (Chapter 2.2).
    """
    settings.require_model_credentials()
    primary = _build_single(settings.model)
    if settings.model_fallback is None:
        return primary
    return FallbackModel(models=[primary, _build_single(settings.model_fallback)])

A missing Gemini key fails when a model is constructed or config:check runs. Read-only tools can import their settings without model credentials. Invalid combinations, including simultaneous API-key and enterprise authentication, still fail configuration validation.

The module does not start an inference server. Gemini requires network access and quota; Ollama requires its separately running server and downloaded model.

Which settings change at each boundary?

Each transition has an explicit configuration change and a separate validation step.

Path Provider Model endpoint Credential
Laptop default gemini Native Gemini API GOOGLE_API_KEY
Host gateway openai-compatible http://127.0.0.1:4000/v1 Non-secret local caller marker; gateway owns upstream key
Kubernetes gateway openai-compatible Cluster-local agentgateway endpoint Gateway caller Secret; separate Gemini provider Secret
Optional local model openai-compatible http://127.0.0.1:11434/v1 Non-secret local-ollama marker

The platform transport is a real change. Re-run tool-result, approval, and evaluation cases rather than assuming a successful HTTP response proves equivalence.

How are retries and timeouts bounded?

The application owns the model deadline and retry count.

Both adapters use AGENT_MODEL_TIMEOUT_S and AGENT_MAX_RETRIES; Gemini also maps the configured backoff. A retried inference request may repeat model work and cost. Guarded writes remain outside automatic retry behavior.

AGENT_MODEL_FALLBACK is an advanced same-provider option, disabled by default. It does not turn Gemini failures into automatic local inference. Switching the learner to Ollama is an explicit configuration choice.

When set, build_model() wraps both models in ADK's experimental FallbackModel. It moves to the second model only after a 429 or 5xx from the first, and only before the first has produced any output. A 4xx request error, a 408 timeout that may already have been processed and billed, or a failure mid-stream reaches the caller unchanged. Each model's own retry policy runs first, so one failure is never retried twice over. Evaluations refuse to run with a fallback set, because every answer would be attributed to the primary.

What proves this page worked?

mise run config:check

You are done when:

  • You can identify your provider, model, endpoint, and credential owner.
  • Configuration passes with credentials masked.
  • You understand which changes require a new live evaluation.

Continue to 2.3. Instructions when you can explain how the model is selected.